/*
 * © 2024 huayunliufeng保留所有权利, 依据MIT许可证发布。
 * 请勿更改或删除版权声明或此文件头。
 * 此代码是免费软件, 您可以重新分发和/或修改它。
 * 开源是希望它有用, 但不对代码做任何保证。
 * 如有疑问请联系: huayunliufeng@163.com
 */

package io.github.huayunliufeng.common.utils;

import org.reflections.Reflections;
import org.reflections.scanners.Scanners;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder;

import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Set;

/**
 * 反射相关工具类。
 *
 * @author huayu 2024/5/16 10:38
 * @version 0.0.1
 * @since 0.0.1
 */
public class HylfReflectUtil {
    /**
     * 查询指定包下, 具有指定注解的类。
     *
     * @param packageName packageName
     * @param annotation  annotation
     * @return 符合条件的类Set集合
     */
    public static Set<Class<?>> getClassForAnnotation(String packageName, Class<? extends Annotation> annotation) {
        Reflections reflections = new Reflections(new ConfigurationBuilder()
                .setUrls(ClasspathHelper.forPackage(packageName))
                .filterInputsBy(new FilterBuilder().includePackage(packageName))
                .setScanners(Scanners.TypesAnnotated)
        );
        return reflections.getTypesAnnotatedWith(annotation);
    }

    /**
     * 尝试将所给类实例化, 请确保所给class有无参构造。
     *
     * @param set set
     * @return Set
     */
    public static Set<Object> newInstance(Set<Class<?>> set) {
        Set<Object> objects = new HashSet<>();
        for (Class<?> aClass : set) {
            String logFormat = "{}实例化失败。";
            HylfFunUtil.methodVoidExec(() -> {
                Object o = aClass.getDeclaredConstructor().newInstance();
                objects.add(o);
            }, logFormat, aClass);
        }
        return objects;
    }
}
